/**
 * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.opsli.modulars.business.valveDevice.web;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.opsli.api.web.business.valveDevice.ValveDeviceRestApi;
import org.opsli.api.wrapper.business.emergency.EmergencyReportModel;
import org.opsli.api.wrapper.business.patrolLocation.PatrolLocationModel;
import org.opsli.api.wrapper.business.patrolStation.PatrolStationModel;
import org.opsli.api.wrapper.business.valveCycle.ValveCycleModel;
import org.opsli.api.wrapper.business.valveDevice.ValveDeviceModel;
import org.opsli.api.wrapper.business.valveDeviceNow.ValveDeviceNowModel;
import org.opsli.api.wrapper.business.valveIp.ValveIpModel;
import org.opsli.api.wrapper.business.valveStation.ValveStationModel;
import org.opsli.api.wrapper.system.org.SysOrgModel;
import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.api.wrapper.system.user.UserWebModel;
import org.opsli.common.annotation.RequiresPermissionsCus;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.opsli.api.base.result.ResultVo;
import org.opsli.common.annotation.ApiRestController;
import org.opsli.common.annotation.EnableLog;
import org.opsli.core.base.controller.BaseRestController;
import org.opsli.core.persistence.Page;
import org.opsli.core.persistence.querybuilder.QueryBuilder;
import org.opsli.core.persistence.querybuilder.WebQueryBuilder;
import org.opsli.core.utils.UserUtil;
import org.opsli.modulars.business.app.web.CoordinatesConvertUtil;
import org.opsli.modulars.business.app.web.MapCordinatesVo;
import org.opsli.modulars.business.app.web.ZkUtils;
import org.opsli.modulars.business.patrolDict.entity.PatrolDict;
import org.opsli.modulars.business.patrolStation.service.IPatrolStationService;
import org.opsli.modulars.business.valveCycle.entity.ValveCycle;
import org.opsli.modulars.business.valveCycle.service.IValveCycleService;
import org.opsli.modulars.business.valveDeviceHis.mapper.ValveDeviceHisMapper;
import org.opsli.modulars.business.valveDeviceHis.service.IValveDeviceHisService;
import org.opsli.modulars.business.valveDeviceNow.entity.ValveDeviceNow;
import org.opsli.modulars.business.valveDeviceNow.mapper.ValveDeviceNowMapper;
import org.opsli.modulars.business.valveDeviceNow.service.IValveDeviceNowService;
import org.opsli.modulars.business.valveDeviceNowHis.mapper.ValveDeviceNowHisMapper;
import org.opsli.modulars.business.valveDeviceNowHis.service.IValveDeviceNowHisService;
import org.opsli.modulars.business.valveIp.entity.ValveIp;
import org.opsli.modulars.business.valveIp.service.IValveIpService;
import org.opsli.modulars.business.valveStation.service.IValveStationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;

import org.opsli.modulars.business.valveDevice.entity.ValveDevice;
import org.opsli.modulars.business.valveDevice.service.IValveDeviceService;

/**
 * 阀门井设备 Controller
 *
 * @author zk
 * @date 2021-10-27 11:01:20
 */
@Api(tags = ValveDeviceRestApi.TITLE)
@Slf4j
@ApiRestController("/valveDevice")
public class ValveDeviceRestController extends BaseRestController<ValveDevice, ValveDeviceModel, IValveDeviceService>
    implements ValveDeviceRestApi {

    @Autowired
    private IValveStationService patrolStationService;
    @Autowired
    private IValveIpService valveIpService;
    @Autowired
    private IValveCycleService valveCycleService;
    @Autowired
    private IValveDeviceNowService nowService;
    @Autowired
    private  IValveDeviceService iService;
    @Autowired
    private IValveDeviceHisService iServiceHis;
    @Autowired
    private IValveDeviceNowHisService nowHisService;
    @Autowired
    private ValveDeviceHisMapper deviceHisMapper;
    @Autowired
    private ValveDeviceNowMapper deviceNowMapper;
    @Autowired
    private ValveDeviceNowHisMapper deviceNowHisMapper;

    /**
    * 阀门井设备 查一条
    * @param model 模型
    * @return ResultVo
    */
    @ApiOperation(value = "获得单条阀门井设备", notes = "获得单条阀门井设备 - ID")
    @RequiresPermissions("valvedevice_select")
    @Override
    public ResultVo<ValveDeviceModel> get(ValveDeviceModel model) {
        // 如果系统内部调用 则直接查数据库
        if(model != null && model.getIzApi() != null && model.getIzApi()){
            model = IService.get(model);
        }
        return ResultVo.success(model);
    }

    /**
    * 阀门井设备 查询分页
    * @param pageNo 当前页
    * @param pageSize 每页条数
    * @param request request
    * @return ResultVo
    */
    @ApiOperation(value = "获得分页数据", notes = "获得分页数据 - 查询构造器")
    /*@RequiresPermissions("valvedevice_select")*/
    @Override
    public ResultVo<?> findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) {

        Map<String,String[]> queryMap = new LinkedHashMap(request.getParameterMap());
        String devid=UserUtil.getSysUser().getCompanyId();
        if(!devid.equals("123")){
            queryMap.put("devid_EQ",new String[]{devid});
        }
        String[] o=queryMap.get("valveName_LIKE");
        if(o!=null){
            String valveName=o[0];
            ValveStationModel valveStationModel=patrolStationService.getOneValve(valveName);
            if(valveStationModel!=null){
                queryMap.put("valueId_EQ",new String[]{valveStationModel.getId()});
            }
            /*System.out.println(valveName);*/
        }
        /*String valveName=queryMap.get("valveName_LIKE").toString();
        System.out.println(valveName);*/
        QueryBuilder<ValveDevice> queryBuilder = new WebQueryBuilder<>(entityClazz, queryMap);
        Page<ValveDevice, ValveDeviceModel> page = new Page<>(pageNo, pageSize);
        page.setQueryWrapper(queryBuilder.build());
        page = IService.findPage(page);
        if(page.getPageData().getRows()!=null&&page.getPageData().getRows().size()>0){
            List<ValveDeviceModel> list=(List<ValveDeviceModel>)page.getPageData().getRows();
            for(ValveDeviceModel model:list){
                ValveStationModel stationModel=patrolStationService.get(model.getValueId());
                model.setValveName(stationModel.getStationName());
                String phone="";
                if(ZkUtils.isBlank(model.getPhone1())){
                    phone=model.getPhone1();
                }
                model.setUploadTime("每"+model.getUploadHour()+"时"+model.getUploadMin()+"分"+model.getUploadSs()+"秒 上传数据");
                if(ZkUtils.isBlank(model.getPhone2())){
                    if(ZkUtils.isBlank(phone)){
                        phone=model.getPhone2();
                    }else{
                        phone=phone+","+model.getPhone2();
                    }
                }
                if(ZkUtils.isBlank(model.getPhone3())){
                    if(ZkUtils.isBlank(phone)){
                        phone=model.getPhone3();
                    }else{
                        phone=phone+","+model.getPhone3();
                    }
                }
                if(ZkUtils.isBlank(model.getPhone4())){
                    if(ZkUtils.isBlank(phone)){
                        phone=model.getPhone4();
                    }else{
                        phone=phone+","+model.getPhone4();
                    }
                }
                if(ZkUtils.isBlank(model.getPhone5())){
                    if(ZkUtils.isBlank(phone)){
                        phone=model.getPhone5();
                    }else{
                        phone=phone+","+model.getPhone5();
                    }
                }
                model.setPhone(phone);

            }
            page.getPageData().setRows(list);
        }

        return ResultVo.success(page.getPageData());
    }



    @Override
    public ResultVo<Map> getList(){
        Map datamap=new HashMap();
        String devid= UserUtil.getSysUser().getCompanyId();
        SysOrgModel smodel=UserUtil.getOrg(devid);
        datamap.put("lt",smodel.getLt());
        datamap.put("ln",smodel.getLn());
        List<ValveDevice> list=IService.findList(devid);
        List<Map> maps=new ArrayList<>();
        Integer num1=0;
        Integer num2=0;
        if(list!=null&&list.size()>0) {
            for (ValveDevice model : list) {
                Map map = new HashMap();
                try {
                    MapCordinatesVo cordinatesVo=new MapCordinatesVo();
                    ValveStationModel stationModel=patrolStationService.get(model.getValueId());
                    cordinatesVo.setLon(new BigDecimal(stationModel.getLongitude()));
                    cordinatesVo.setLat(new BigDecimal(stationModel.getDimension()));
                    cordinatesVo= CoordinatesConvertUtil.bd_encrypt(cordinatesVo);
                    ValveDeviceNowModel deviceNow=nowService.getOne(model.getDeviceId());
                    if(deviceNow==null){
                        deviceNow=new ValveDeviceNowModel();
                    }
                    map.put("stationName", stationModel.getStationName());
                    map.put("longitude", cordinatesVo.getLon());
                    map.put("dimension",cordinatesVo.getLat());
                    map.put("id", stationModel.getId());
                    map.put("voltage", deviceNow.getVoltage());
                    map.put("potency", deviceNow.getPotency());
                    map.put("lastTime", deviceNow.getLastTime());
                    map.put("bit0", deviceNow.getBit0());
                    map.put("bit1", deviceNow.getBit0());
                    map.put("bit2", deviceNow.getBit2());
                    map.put("bit3", deviceNow.getBit3());
                    map.put("bit4", deviceNow.getBit0());
                    map.put("bit5", deviceNow.getBit0());
                    map.put("bit6", deviceNow.getBit6());
                    map.put("lastPic", stationModel.getLastPic());
                    map.put("lastVideo", stationModel.getLastVideo());
                    map.put("type", model.getAlarmState());
                    if(model.getAlarmState().equals("0")){
                        num1++;
                    }else{
                        num2++;
                    }
                    map.put("deviceId", model.getDeviceId());
                    maps.add(map);
                }catch (Exception e){
                    System.out.println("坐标转换异常="+ JSON.toJSONString(model));
                }

            }
        }
        datamap.put("list",maps);
        datamap.put("num1",num1);
        datamap.put("num2",num2);
        datamap.put("num",num2+num1);
        return ResultVo.success(datamap);
    }

    /**
    * 阀门井设备 新增
    * @param model 模型
    * @return ResultVo
    */
    @ApiOperation(value = "新增阀门井设备数据", notes = "新增阀门井设备数据")
    /*@RequiresPermissions("valvedevice_insert")*/
    @EnableLog
    @Override
    public ResultVo<?> insert(ValveDeviceModel model) {
        model.setDevid(UserUtil.getSysUser().getCompanyId());
        // 调用新增方法
        IService.insert(model);
        return ResultVo.success("新增阀门井设备成功");
    }

    /**
    * 阀门井设备 修改
    * @param model 模型
    * @return ResultVo
    */
    @ApiOperation(value = "修改阀门井设备数据", notes = "修改阀门井设备数据")
    /*@RequiresPermissions("valvedevice_update")*/
    @EnableLog
    @Override
    public ResultVo<?> update(ValveDeviceModel model) {
        // 调用修改方法
        IService.update(model);
        return ResultVo.success("修改阀门井设备成功");
    }

    @Override
    public ResultVo<?> updateIp(ValveDeviceModel model) {
        ValveDeviceModel oldmodel=IService.get(model.getId());
        // 调用修改方法
        IService.update(model);
        if(ZkUtils.isNotBlank(oldmodel.getServerIp())){
            ValveIp valveIp=valveIpService.getDeviceIp(oldmodel.getDeviceId());
            if(valveIp==null){
                ValveIpModel ipModel=new ValveIpModel();
                ipModel.setDevid(oldmodel.getDevid());
                ipModel.setDeviceId(oldmodel.getDeviceId());
                ipModel.setServerIp(model.getServerIp());
                ipModel.setServerPort(model.getServerPort());
                ipModel.setServerApn(model.getServerApn());
                valveIpService.insert(ipModel);
            }else{
                ValveIpModel ipModel=new ValveIpModel();
                ipModel.setId(valveIp.getId());
                ipModel.setDevid(oldmodel.getDevid());
                ipModel.setDeviceId(oldmodel.getDeviceId());
                ipModel.setServerIp(model.getServerIp());
                ipModel.setServerPort(model.getServerPort());
                ipModel.setServerApn(model.getServerApn());
                valveIpService.update(ipModel);
            }
        }
        return ResultVo.success("修改阀门井设备成功");
    }

    @Override
    public ResultVo<?> updateCycle(ValveDeviceModel model) {
        ValveDeviceModel oldmodel=IService.get(model.getId());
        // 调用修改方法
        IService.update(model);
        if(ZkUtils.isNotBlank(oldmodel.getCollectTime())){
            ValveCycle valveCycle=valveCycleService.getDeviceCycle(oldmodel.getDeviceId());
            if(valveCycle==null){
                ValveCycleModel ipModel=new ValveCycleModel();
                ipModel.setDevid(oldmodel.getDevid());
                ipModel.setDeviceId(oldmodel.getDeviceId());
                ipModel.setCollectTime(model.getCollectTime());
                ipModel.setUploadHour(model.getUploadHour());
                ipModel.setUploadMin(model.getUploadMin());
                ipModel.setUploadSs(model.getUploadSs());
                valveCycleService.insert(ipModel);
            }else{
                ValveCycleModel ipModel=new ValveCycleModel();
                ipModel.setId(valveCycle.getId());
                ipModel.setDevid(oldmodel.getDevid());
                ipModel.setDeviceId(oldmodel.getDeviceId());
                ipModel.setCollectTime(model.getCollectTime());
                ipModel.setUploadHour(model.getUploadHour());
                ipModel.setUploadMin(model.getUploadMin());
                ipModel.setUploadSs(model.getUploadSs());
                valveCycleService.update(ipModel);
            }
        }
        return ResultVo.success("修改阀门井设备成功");
    }


    @Override
    public ResultVo<?> updateState(String id){
        ValveDeviceModel valveDeviceModel=new ValveDeviceModel();
        valveDeviceModel.setId(id);
        valveDeviceModel.setAlarmState("0");
        iService.update(valveDeviceModel);
        return ResultVo.success("解除报警成功");
    }

    /**
    * 阀门井设备 删除
    * @param id ID
    * @return ResultVo
    */
    @ApiOperation(value = "删除阀门井设备数据", notes = "删除阀门井设备数据")
    /*@RequiresPermissions("valvedevice_update")*/
    @EnableLog
    @Override
    public ResultVo<?> del(String id){

        //删除阀门井设备的同时 也把阀门井的
        //历史数据
        //根据阀门井编号删除历史数据
        ValveDeviceModel device= iService.get(id);
        IService.delete(id);
        deviceHisMapper.delHis(device.getValueId());
//        iServiceHis.delete(device.getValueId());
        //实时数据  实时历史数据
        deviceNowMapper.delNow(device.getValueId());
//        nowService.delete(device.getValueId());
        deviceNowHisMapper.delNowHis(device.getValueId());
//        nowHisService.delete(device.getValueId());

        return ResultVo.success("删除阀门井设备成功");
    }

    /**
    * 阀门井设备 批量删除
    * @param ids ID 数组
    * @return ResultVo
    */
    @ApiOperation(value = "批量删除阀门井设备数据", notes = "批量删除阀门井设备数据")
    @RequiresPermissions("valvedevice_update")
    @EnableLog
    @Override
    public ResultVo<?> delAll(String ids){
        String[] idArray = Convert.toStrArray(ids);
        IService.deleteAll(idArray);
        return ResultVo.success("批量删除阀门井设备成功");
    }


    /**
    * 阀门井设备 Excel 导出
    * 注：这里 RequiresPermissionsCus 引入的是 自定义鉴权注解
    *
    * 导出时，Token认证和方法权限认证 全部都由自定义完成
    * 因为在 导出不成功时，需要推送错误信息，
    * 前端直接走下载流，当失败时无法获得失败信息，即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时
    * ，且如果数据量过大，前端进行渲染时直接会把浏览器卡死
    * 而直接开启socket接口推送显然是太过浪费资源了，所以目前采用Java最原始的手段
    * response 推送 javascript代码 alert 提示报错信息
    *
    * @param request request
    * @param response response
    */
    @ApiOperation(value = "导出Excel", notes = "导出Excel")
    @RequiresPermissionsCus("valvedevice_export")
    @EnableLog
    @Override
    public void exportExcel(HttpServletRequest request, HttpServletResponse response) {
        // 当前方法
        Method method = ReflectUtil.getMethodByName(this.getClass(), "exportExcel");
        QueryBuilder<ValveDevice> queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap());
        super.excelExport(ValveDeviceRestApi.SUB_TITLE, queryBuilder.build(), response, method);
    }

    /**
    * 阀门井设备 Excel 导入
    * 注：这里 RequiresPermissions 引入的是 Shiro原生鉴权注解
    * @param request 文件流 request
    * @return ResultVo
    */
    @ApiOperation(value = "导入Excel", notes = "导入Excel")
    @RequiresPermissions("valvedevice_import")
    @EnableLog
    @Override
    public ResultVo<?> importExcel(MultipartHttpServletRequest request) {
        return super.importExcel(request);
    }

    /**
    * 阀门井设备 Excel 下载导入模版
    * 注：这里 RequiresPermissionsCus 引入的是 自定义鉴权注解
    * @param response response
    */
    @ApiOperation(value = "导出Excel模版", notes = "导出Excel模版")
    @RequiresPermissionsCus("valvedevice_import")
    @Override
    public void importTemplate(HttpServletResponse response) {
        // 当前方法
        Method method = ReflectUtil.getMethodByName(this.getClass(), "importTemplate");
        super.importTemplate(ValveDeviceRestApi.SUB_TITLE, response, method);
    }

}
